package com.elitel.common.businessJdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;

import com.elitel.common.exception.BusinessStatementException;

import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

// here is handle update relative sql h
@Component
@Slf4j
public class BusinessUpdatePreparedStatementHandler extends BusinessPreparedStatementHandler{

    public int updateTableRowData(BusinessUpdatePreparedStatement bps){
        //
        // here is build sql message
        String precompileSql = bps.getPrecompileSql();
        SqlRecorder recorder = new SqlRecorder();
        recorder.setServiceGuid(bps.getServiceGuid());
        recorder.setPrecompileSql(precompileSql);

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        int rows = 0;

        try{

            connection = getConnection();
            preparedStatement = connection.prepareStatement(precompileSql);

            int parameterIndex = 1;
            // here is set update column
            parameterIndex = handlePlaceHolderColumnValue(recorder, bps, preparedStatement, parameterIndex, bps.getUpdateColumnMap());
            // here is set where condition column
            handlePlaceHolderColumnValue(recorder, bps, preparedStatement, parameterIndex, bps.getConditionColumnMap());

            if(recorder.canExecuteSql()){
                log.info(recorder.formatInfo());
            }else{
                log.error(recorder.formatInfo());
            }

            rows = preparedStatement.executeUpdate();

            // close resource.
            preparedStatement.close();
            connection.close();

        }catch(Exception e){
            log.error("Update Fail; " + e.getMessage());
            e.printStackTrace();

            try{
                if(preparedStatement != null) preparedStatement.close();
                if(connection != null) connection.close();
            }catch(SQLException sqlE){
                log.error(sqlE.getMessage());
            }

            throw new BusinessStatementException(e.getMessage(), recorder.formatInfo());
        }

        return rows;
    }

    private int handlePlaceHolderColumnValue(SqlRecorder recorder, BusinessUpdatePreparedStatement bps, PreparedStatement ps, int parameterIndex, Map<String, Object> columnMap) throws Exception {
        for(Map.Entry<String, Object> columnEntry : columnMap.entrySet()){
            String columnName = columnEntry.getKey();
            Object columnValue = columnEntry.getValue();
            String fieldType = bps.getFieldTypeMap().get(columnName);

            String parameterInfo = "index = " + parameterIndex + " contionItem: " + columnName + " = " + columnValue + " fieldType = " + fieldType;
            try{
                if(matchPreparedStatementSetMethodByFieldType(bps.getDatabaseType(), ps, parameterIndex++, columnValue, fieldType)){
                    recorder.addParameterInformation(parameterInfo);
                }else{
                    recorder.addParameterInformation("FAIL: " + parameterInfo);
                    recorder.addErrorMessage("FAIL: matchPreparedStatementSetMethodByFieldType match false, because of " + parameterInfo);

                }
            }catch(Exception e){
                recorder.addParameterInformation("FAIL: " + parameterInfo);
                recorder.addErrorMessage(e.getMessage());
            }
        }
        return parameterIndex;
    }

}
